﻿<Serializable()>
Public Class ProjectElement
    Implements ICloneable
    Private Contat As Integer
    Private pElementRemark As String
    Private NameValue As String = "Fase"
    Private WithEvents pGroups As New VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Group)
    Private WithEvents pMilestones As New VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Milestone)
    Public Event HeightChanged(ByVal sender As L3DObjectsLibrary.ProjectElement)
    Public Event WidthChanged(ByVal sender As L3DObjectsLibrary.ProjectElement)
    Public Event NowEmpty(ByVal sender As L3DObjectsLibrary.ProjectElement)
    Public Event Redrawed(ByVal sender As L3DObjectsLibrary.ProjectElement)
    Friend Event DateChanged(ByVal sender As Object, ByVal e As L3DObjectsLibrary.DateChangedEventArgs)
    Public Event CarEnteringEditMode(ByVal sender As Object, ByVal Car As L3DObjectsLibrary.Car)
    Public Event QueryChange(ByVal sender As Object, ByVal e As QueryChangeEventArgs)


#Region "PROPERTIES"
    Public ReadOnly Property MilestoneSpecialID As Integer
        Get
            Dim Result As Integer
            For Each Milestone As L3DObjectsLibrary.Milestone In Milestones
                Result = Milestone.SpecialID
            Next
            Return Result
        End Get
    End Property
    Public ReadOnly Property HasSpecialIDMilestones As L3DObjectsLibrary.Milestone.SpecialIDValues
        Get
            Dim Result As Integer = L3DObjectsLibrary.Milestone.SpecialIDValues.None
            For Each Milestone As L3DObjectsLibrary.Milestone In Milestones
                If Milestone.SpecialID <> L3DObjectsLibrary.Milestone.SpecialIDValues.None Then
                    Result = Milestone.SpecialID
                End If
            Next
            Return Result
        End Get
    End Property
    Public ReadOnly Property SpecialID As Milestone.SpecialIDValues
        Get
            Dim Result As Integer = 1
            For Each Milestone As L3DObjectsLibrary.Milestone In Milestones
                If Milestone.SpecialID <> L3DObjectsLibrary.Milestone.SpecialIDValues.None Then
                    Result = Milestone.SpecialID
                    Exit For
                End If
            Next
            Return result
        End Get
    End Property
    Public Property Remark As String
        Get
            Return pElementRemark
        End Get
        Set(ByVal value As String)
            pElementRemark = value
        End Set
    End Property
    Public Property Name As String
        Get
            Return NameValue
        End Get
        Set(ByVal value As String)
            NameValue = value
        End Set
    End Property
    Public ReadOnly Property ElementType As ElementTypeValue
        Get
            If Me.Groups.Count > 0 And Me.Milestones.Count > 0 Then
                Return ElementTypeValue.L3DMixed
            ElseIf Me.Groups.Count = 0 And Milestones.Count > 0 Then
                Return ElementTypeValue.L3DMilestone
            ElseIf Me.Groups.Count > 0 And Milestones.Count = 0 Then
                Return ElementTypeValue.L3DPhase
            Else
                Return ElementTypeValue.L3DUndefined
            End If
        End Get
    End Property
    Public ReadOnly Property ElementStartDate As Date
        Get
            Dim StartDateGroups As Date
            Dim StartDateMilestones = FirstMilestoneDate.Plan
            For Each Group As L3DObjectsLibrary.Group In Me.Groups
                If DateTime.Compare(StartDateGroups, Group.GroupStartDate) > 0 Or Group Is Groups.First Then
                    StartDateGroups = Group.GroupStartDate
                End If
            Next
            If Groups.Count = 0 Then
                StartDateGroups = StartDateMilestones
            ElseIf Milestones.Count = 0 Then
                StartDateMilestones = StartDateGroups
            End If
            Return VMGenLibrary.DateTimeOperations.FirstDate(StartDateGroups, StartDateMilestones)
        End Get
    End Property
    Public ReadOnly Property ElementEndDate As Date
        Get
            Dim EndDateGroups As Date
            Dim EndDateMilestones As Date
            For Each Group As L3DObjectsLibrary.Group In Me.Groups
                If DateTime.Compare(EndDateGroups, Group.GroupEndDate) < 0 Or Group Is Groups.First Then
                    EndDateGroups = Group.GroupEndDate
                End If
            Next
            For Each Milestone As L3DObjectsLibrary.Milestone In Milestones
                If DateTime.Compare(EndDateMilestones, Milestone.MilestoneDate) < 0 Or Milestone Is Milestones.First Then
                    EndDateMilestones = Milestone.MilestoneDate
                End If
            Next
            If Groups.Count = 0 Then
                EndDateGroups = EndDateMilestones
            ElseIf Milestones.Count = 0 Then
                EndDateMilestones = EndDateGroups
            End If
            Return VMGenLibrary.DateTimeOperations.FirstDate(EndDateGroups, EndDateMilestones)
        End Get
    End Property
    Public ReadOnly Property ElementRealEndDate As Date
        Get
            Dim RealEndDateGroups As Date
            Dim RealEndDateMilestones As Date
            For Each Group As L3DObjectsLibrary.Group In Me.Groups
                If DateTime.Compare(RealEndDateGroups, Group.GroupRealEndDate) < 0 Or Group Is Groups.First Then
                    RealEndDateGroups = Group.GroupRealEndDate
                End If
            Next
            For Each Milestone As L3DObjectsLibrary.Milestone In Milestones
                If DateTime.Compare(RealEndDateMilestones, Milestone.MilestoneDate) < 0 Or Milestone Is Milestones.First Then
                    RealEndDateMilestones = Milestone.MilestoneDate
                End If
            Next
            If Groups.Count = 0 Then
                RealEndDateGroups = RealEndDateMilestones
            ElseIf Milestones.Count = 0 Then
                RealEndDateMilestones = RealEndDateGroups
            End If
            Return VMGenLibrary.DateTimeOperations.FirstDate(RealEndDateGroups, RealEndDateMilestones)
        End Get
    End Property
    Public ReadOnly Property ElementRealStartDate As Date
        Get
            Dim RealStartDateGroups As Date
            Dim RealStartDateMilestones As Date
            For Each Group As L3DObjectsLibrary.Group In Me.Groups
                If Date.Compare(RealStartDateGroups, Group.GroupRealStartDate) > 0 Or Group Is Groups.First Then
                    RealStartDateGroups = Group.GroupRealStartDate
                End If
            Next
            If Groups.Count = 0 And Milestones.Count <> 0 Then
                RealStartDateMilestones = FirstMilestoneDate.Plan
                RealStartDateGroups = RealStartDateMilestones
            ElseIf Milestones.Count = 0 Then
                RealStartDateMilestones = RealStartDateGroups
            End If
            Return VMGenLibrary.DateTimeOperations.FirstDate(RealStartDateGroups, RealStartDateMilestones)
        End Get
    End Property
    Public ReadOnly Property FirstMilestoneDate As Milestone.MilestoneTiming
        Get
            Dim Result As Milestone.MilestoneTiming
            For Each Milestone In Milestones
                If Milestone Is Milestones.First Then
                    Result = New Milestone.MilestoneTiming
                End If
                If Milestone.MilestoneRealDate < Result.RePlan Or Milestone Is Milestones.First Then
                    With Result
                        .RePlan = Milestone.MilestoneRealDate
                    End With
                End If
                If Milestone.MilestoneDate < Result.Plan Or Milestone Is Milestones.First Then
                    With Result
                        .Plan = Milestone.MilestoneDate
                    End With
                End If
            Next
            Return Result
        End Get
    End Property
    Public ReadOnly Property MinDate As Date
        Get
            Dim Ar As New ArrayList
            With Ar
                .Add(ElementStartDate)
                .Add(ElementRealStartDate)
                .Sort()
            End With
            Return Ar(0)
        End Get
    End Property
    Public ReadOnly Property MaxDate As Date
        Get
            Dim Ar As New ArrayList
            With Ar
                .Add(ElementEndDate)
                .Add(ElementRealEndDate)
                .Sort()
            End With
            Return Ar(Ar.Count - 1)
        End Get
    End Property
    Public Property Groups As PowerCollection(Of L3DObjectsLibrary.Group)
        Get
            Return pGroups
        End Get
        Set(ByVal value As PowerCollection(Of L3DObjectsLibrary.Group))
            pGroups.Dispose()
            pGroups = value
        End Set
    End Property
    Public Property Milestones As VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Milestone)
        Get
            Return pMilestones
        End Get
        Set(ByVal value As VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Milestone))
            pMilestones.Dispose()
            pMilestones = value
        End Set
    End Property
    Public ReadOnly Property HasEOBDCar As Boolean
        Get
            Dim Controllo As Boolean = False
            For Each Gruppo As L3DObjectsLibrary.Group In Me.Groups
                If Gruppo.HasEOBDCar = True Then
                    Controllo = True
                    Exit For
                End If
            Next
            Return Controllo
        End Get
    End Property
    Public ReadOnly Property AllCars(Optional ByVal EOBDOnly As Boolean = False, Optional ByVal EOBDExclude As Boolean = False) As Collection
        Get
            Dim Cars As New Collection
            For Each Gruppo As L3DObjectsLibrary.Group In Me.Groups
                For Each Car As L3DObjectsLibrary.Car In Gruppo.Cars
                    If (Car.EOBD = True And EOBDOnly = True) Or (Car.EOBD = False And EOBDExclude = True) Or (EOBDOnly = False And EOBDExclude = False) Then
                        Cars.Add(Car)
                    End If
                Next
            Next
            Return Cars
        End Get
    End Property
    Public ReadOnly Property AllCarsKm(Optional ByVal EOBDOnly As Boolean = False, Optional ByVal EOBDExclude As Boolean = False) As Integer
        Get
            Dim km As Integer
            For Each Group As L3DObjectsLibrary.Group In Me.Groups
                km = km + Group.AllCarsKm(EOBDOnly, EOBDExclude)
            Next
            Return km
        End Get
    End Property
#End Region
#Region "METHODS"
    Public Function MileageForecast(ByVal CurrentStatusDate As Date, ByVal ForecastStatusDate As Date, Optional ByVal EOBDOnly As Boolean = False, Optional ByVal EOBDExclude As Boolean = False) As Integer
        Dim KmForecast As Integer
        For Each Group As L3DObjectsLibrary.Group In Me.Groups
            KmForecast = KmForecast + Group.MileageForecast(CurrentStatusDate, ForecastStatusDate, EOBDOnly, EOBDExclude)
        Next
        Return KmForecast
    End Function
    Public Sub Translate(ByVal Days As Integer)
        For Each G As Group In Groups
            For Each C As Car In G.Cars
                With C
                    .CarStartDate = DateAdd(DateInterval.Day, Days, .CarStartDate)
                    .CarEndDate = DateAdd(DateInterval.Day, Days, .CarEndDate)
                    .CarRealStartDate = DateAdd(DateInterval.Day, Days, .CarRealStartDate)
                    .CarRealEndDate = DateAdd(DateInterval.Day, Days, .CarRealEndDate)
                End With
            Next
        Next
        For Each M As Milestone In Milestones
            With M
                .MilestoneDate = DateAdd(DateInterval.Day, Days, .MilestoneDate)
                .MilestoneRealDate = DateAdd(DateInterval.Day, Days, .MilestoneRealDate)
            End With
        Next
    End Sub
    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim El As ProjectElement = CType(ObjManagement.CloneObject(Me), ProjectElement)
        For Each Gr As Group In El.Groups
            El.AddRemoveGroupHandlers(Gr, AddRemove.Add)
        Next
        Return El
    End Function
    Private Sub AddRemoveGroupHandlers(ByVal Group As Group, ByVal Action As AddRemove)
        With Group
            Select Case Action
                Case AddRemove.Add
                    AddHandler .NowEmpty, AddressOf Group_NowEmpty
                    AddHandler .DateChanged, AddressOf Group_DateChanged
                    AddHandler .QueryChange, AddressOf Group_QueryChange
                Case AddRemove.Remove
                    RemoveHandler .NowEmpty, AddressOf Group_NowEmpty
                    RemoveHandler .DateChanged, AddressOf Group_DateChanged
                    RemoveHandler .QueryChange, AddressOf Group_QueryChange
            End Select
        End With
    End Sub
#End Region
#Region "EVENTS"
    Private Sub Group_DateChanged(ByVal sender As Object, ByVal e As L3DObjectsLibrary.DateChangedEventArgs)
        RaiseEvent DateChanged(Me, e)
    End Sub
    Private Sub Group_NowEmpty(ByVal sender As L3DObjectsLibrary.Group)
        Dim Index As Integer = Groups.IndexOf(sender)
        If Index > -1 Then
            Groups.RemoveAt(Index)
        End If
    End Sub
    Private Sub Group_QueryChange(ByVal sender As Object, ByVal e As QueryChangeEventArgs)
        RaiseEvent QueryChange(Me, New QueryChangeEventArgs)
    End Sub
    Private Sub Groups_CountChanging(ByVal sender As VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Group), ByVal e As VMGenLibrary.Structures.PowercollectionEventArgs) Handles pGroups.CountChanging, pGroups.ItemsExchanging, pGroups.ItemsMoving
        RaiseEvent QueryChange(Me, New QueryChangeEventArgs)
    End Sub
    Private Sub Groups_CountChanged(ByVal sender As VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Group), ByVal e As VMGenLibrary.Structures.PowercollectionEventArgs) Handles pGroups.CountChanged
        Dim Group As L3DObjectsLibrary.Group = e.ObjectMoved
        With Group
            If e.Action = CountChangedAction.Added Then
                AddRemoveGroupHandlers(Group, AddRemove.Add)
            ElseIf e.Action = CountChangedAction.Removed Then
                AddRemoveGroupHandlers(Group, AddRemove.Remove)
            End If
            RaiseEvent DateChanged(Me, New L3DObjectsLibrary.Structures.DateChangedEventArgs)
        End With
    End Sub
    Private Sub Milestones_CountChanging(ByVal sender As PowerCollection(Of Milestone), ByVal e As PowercollectionEventArgs) Handles pMilestones.CountChanging, pMilestones.ItemsExchanging, pMilestones.ItemsMoving
        RaiseEvent QueryChange(Me, New QueryChangeEventArgs)
    End Sub
    Private Sub Groups_NowEmpty(ByVal sender As VMGenLibrary.VMObjects.PowerCollection(Of L3DObjectsLibrary.Group)) Handles pGroups.NowEmpty
        RaiseEvent NowEmpty(Me)
    End Sub
#End Region
End Class
